from pluginsCategories import pySKFWServices
import os,sys,logging,threading
from opencv.cv import *
from opencv.highgui import *

class pySKFWImage(pySKFWServices):
    name = 'pySKFWImage'
    tmpPath = '/tmp/'
    capture = None
    def init(self,server):
        self.server = server
        self.provides = {
            'imageGetter' : {'handler':self.getJpegMotionPicture ,'resultType':'img','path':r'/cv/motion(.*)'},
            'imageGetterR': {'handler':self.getJpegPicture ,'resultType':'img','path':r'/cv/capture(.*)'}
        }
        self.getPictureSemaphore = threading.BoundedSemaphore(1)        

        self.capture =  cvCreateCameraCapture(0)
        if self.capture == None:
            logging.info(" Error initializing Serving images ...")
            return;
        logging.info(" Serving images ...")
        self.tmp = cvQueryFrame(self.capture)
        smallSize = CvSize()
        smallSize.width = 320
        smallSize.height= 240
        self.color_image = cvCreateImage(smallSize, IPL_DEPTH_8U,3)
        cvResize(self.tmp,self.color_image)
        cvFlip(self.color_image,self.color_image,1)	
        self.grey_image = cvCreateImage(smallSize, IPL_DEPTH_8U, 1)
        self.moving_average = cvCreateImage(smallSize, IPL_DEPTH_32F, 3)
        self.difference = None
        logging.info(" Serving images OK %s" % CV_CAP_PROP_FRAME_HEIGHT)        
        cvResize(self.tmp,self.color_image)
        self.server.initTimer(self.name,'getPicture',1,self.tickPicture)
        
    def tickPictureSimple(self):
        if self.capture == None:
            return;
        self.getPictureSemaphore.acquire()
        #logging.info("get image %scap.jpg " % self.tmpPath)
        self.color_image = cvQueryFrame(self.capture)
        cvSaveImage(self.tmpPath+ 'cap.jpg',self.color_image)
        self.getPictureSemaphore.release()

    def tickPicture(self):
        if self.capture == None:
            return;
        self.getPictureSemaphore.acquire()
        #logging.info("get image %scap.jpg " % self.tmpPath)
        cvResize(cvQueryFrame(self.capture),self.color_image)
        cvFlip(self.color_image,self.color_image,1)	
        cvSaveImage(self.tmpPath+ 'cap.jpg',self.color_image)
        # Smooth to get rid of false positives
        cvSmooth(self.color_image, self.color_image, CV_GAUSSIAN, 3, 0)
        if not self.difference:
            # Initialize
            self.difference = cvCloneImage(self.color_image)
            self.temp = cvCloneImage(self.color_image)
            cvConvertScale(self.color_image, self.moving_average, 1.0, 0.0)
        else:
            cvRunningAvg(self.color_image, self.moving_average, 0.020, None)
        cvConvertScale(self.moving_average, self.temp, 1.0, 0.0)
        # Minus the current frame from the moving average.
        cvAbsDiff(self.color_image, self.temp, self.difference)
        # Convert the image to grayscale.
        cvCvtColor(self.difference, self.grey_image, CV_RGB2GRAY)
        # Convert the image to black and white.
        cvThreshold(self.grey_image, self.grey_image, 70, 255, CV_THRESH_BINARY)
        # Dilate and erode to get object blobs
        cvDilate(self.grey_image, self.grey_image, None, 18)
        cvErode(self.grey_image, self.grey_image, None, 10)
        # Calculate movements
        self.storage = cvCreateMemStorage(0)
        nb,contour = cvFindContours(self.grey_image, self.storage, sizeof_CvContour,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE)
        points = []
        while contour:
                # Draw rectangles
                bound_rect = cvBoundingRect(contour)
                contour = contour.h_next
                pt1 = (bound_rect.x, bound_rect.y)
                pt2 = (bound_rect.x + bound_rect.width, bound_rect.y + bound_rect.height)
                points.append(pt1)
                points.append(pt2)
                cvRectangle(self.color_image, pt1, pt2, CV_RGB(255,0,0), 1)
                
        num_points = len(points)
        if num_points:
            # Draw bullseye in midpoint of all movements
            x = y = 0
            for point in points:
                x += point[0]
                y += point[1]
            x /= num_points
            y /= num_points
            center_point = (x, y)
            cvCircle(self.color_image, center_point, 40, CV_RGB(255, 255, 255), 1)
            cvCircle(self.color_image, center_point, 30, CV_RGB(255, 100, 0), 1)
            cvCircle(self.color_image, center_point, 20, CV_RGB(255, 255, 255), 1)
            cvCircle(self.color_image, center_point, 10, CV_RGB(255, 100, 0), 5)
        cvSaveImage(self.tmpPath+ 'motion.jpg',self.color_image)
        #logging.info("reco %s "% num_points)
        self.getPictureSemaphore.release()
        
    def getJpegPicture(self,ts):
        logging.info("get image %scap.jpg " % self.tmpPath)
        filePath = self.tmpPath+ 'cap.jpg'
        return self.getJpg(filePath)

    def getJpegMotionPicture(self,ts):
        filePath = self.tmpPath+ 'motion.jpg'
        return self.getJpg(filePath)
        #logging.info("get image motion.jpg ")

    def getJpg(self,filename):
        if (os.path.exists(filename)):
            self.getPictureSemaphore.acquire()
            raw_file=open(filename)
            tmp = raw_file.read()        
            self.getPictureSemaphore.release()
            return tmp
        else:
            return None